package com.sq.auth.domain.service.impl;

import cn.dev33.satoken.secure.SaSecureUtil;
import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.google.gson.Gson;
import com.sq.auth.common.enums.AuthUserStatusEnum;
import com.sq.auth.common.enums.IsDeletedFlagEnum;
import com.sq.auth.domain.bo.AuthUserBO;
import com.sq.auth.domain.constans.AuthConstant;
import com.sq.auth.domain.redis.RedisUtil;
import com.sq.auth.domain.service.AuthUserDomainService;
import com.sq.auth.infra.basic.entity.*;
import com.sq.auth.infra.basic.service.*;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @author quan
 */
@Service
public class AuthUserDomainServiceImpl implements AuthUserDomainService {

    @Resource
    private AuthUserService authUserService;
    @Resource
    private AuthRoleService authRoleService;

    @Resource
    private AuthUserRoleService authUserRoleService;

    @Resource
    private AuthPermissionService authPermissionService;

    @Resource
    private AuthRolePermissionService authRolePermissionService;

    @Resource
    private RedisUtil redisUtil;

    private String salt = "quan";


    private String authRolePrefix = "auth.role";
    private String authPermissionPrefix = "auth.permission";

    private String loginKeyPrefix = "loginCode";


    @Override
    public boolean register(AuthUserBO authUserBO) {
        //校验用户是否存在
        AuthUser existAuthUser = new AuthUser();
        existAuthUser.setUserName(authUserBO.getUserName());
        List<AuthUser> existUser = authUserService.queryByCondition(existAuthUser);
        if (existUser.size() > 0) {
            return true;
        }
        AuthUser authUser = BeanUtil.copyProperties(authUserBO, AuthUser.class);
        authUser.setIsDeleted(IsDeletedFlagEnum.UN_DELETED.getCode());
        authUser.setStatus(AuthUserStatusEnum.OPEN.getCode());
        if (StrUtil.isNotBlank(authUser.getPassword())) {
            authUser.setPassword(SaSecureUtil.md5BySalt(authUser.getPassword(), salt));
        }
        if (StrUtil.isBlank(authUser.getAvatar())) {
            authUser.setAvatar("http://117.72.10.84:9000/user/icon/微信图片_20231203153718(1).png");
        }
        if (StrUtil.isBlank(authUser.getNickName())) {
            authUser.setNickName("权哥粉丝");
        }


        int insert = authUserService.insert(authUser);
        //绑定默认角色
        AuthRole authRole = new AuthRole();
        authRole.setRoleKey(AuthConstant.MANGER_USER);
        List<AuthRole> authRoleList = authRoleService.queryByCondition(authRole);
        if(CollUtil.isEmpty(authRoleList)){
            return insert > 0;
        }
        AuthRole role = authRoleList.get(0);
        Long userId = authUser.getId();
        Long roleId = role.getId();
        AuthUserRole authUserRole = new AuthUserRole();
        authUserRole.setUserId(userId);
        authUserRole.setRoleId(roleId);
        authUserRole.setIsDeleted(IsDeletedFlagEnum.UN_DELETED.getCode());
        authUserRoleService.insert(authUserRole);
        //将角色、权限信息放入到Redis中

        String roleKey = redisUtil.buildKey(authRolePrefix, authUser.getUserName());
        List<AuthRole> roleList = new ArrayList<>();
        roleList.add(role);
        redisUtil.set(roleKey, new Gson().toJson(roleList));
        AuthRolePermission authRolePermission = new AuthRolePermission();
        authRolePermission.setRoleId(roleId);
        List<AuthRolePermission> authRolePermissionList = authRolePermissionService.queryByCondition(authRolePermission);
        List<Long> permissionIds = authRolePermissionList.stream().map(AuthRolePermission::getPermissionId).toList();
        List<AuthPermission> authPermissionList = authPermissionService.queryByPermissionIds(permissionIds);
        String permissionKey = redisUtil.buildKey(authPermissionPrefix, authUser.getUserName());
        redisUtil.set(permissionKey, new Gson().toJson(authPermissionList));
        return insert > 0;
    }

    @Override
    public boolean update(AuthUserBO authUserBO) {
        AuthUser authUser = BeanUtil.copyProperties(authUserBO, AuthUser.class);
        authUser.setIsDeleted(IsDeletedFlagEnum.UN_DELETED.getCode());
        int update = authUserService.updateByUserName(authUser);
        return update > 0;
    }

    @Override
    public AuthUserBO getUserInfo(AuthUserBO authUserBO) {
        AuthUser authUser = BeanUtil.copyProperties(authUserBO, AuthUser.class);
        List<AuthUser> authUserList = this.authUserService.queryByCondition(authUser);
        if(CollectionUtil.isEmpty(authUserList)){
            return new AuthUserBO();
        }
        AuthUser user = authUserList.get(0);
        return BeanUtil.copyProperties(user,AuthUserBO.class);
    }

    @Override
    public boolean delete(AuthUserBO authUserBO) {
        AuthUser authUser = BeanUtil.copyProperties(authUserBO, AuthUser.class);
        AuthUser user = new AuthUser();
        user.setId(authUser.getId());
        user.setIsDeleted(IsDeletedFlagEnum.DELETED.getCode());
        int delete = authUserService.update(user);
        return delete > 0;
    }

    @Override
    public SaTokenInfo doLogin(String validCode) {
        String loginKey = redisUtil.buildKey(loginKeyPrefix, validCode);
        String openId = redisUtil.get(loginKey);
        if(StrUtil.isBlank(openId)){
            return null;
        }
        AuthUser authUser = new AuthUser();
        authUser.setUserName(openId);
        this.register(BeanUtil.copyProperties(authUser,AuthUserBO.class));
        StpUtil.login(openId);
        return StpUtil.getTokenInfo();
    }

    @Override
    public List<AuthUserBO> listUserInfoByIds(List<String> userNameList) {
        List<AuthUser> userList = authUserService.listUserInfoByIds(userNameList);
        if (CollectionUtils.isEmpty(userList)) {
            return Collections.emptyList();
        }
        return BeanUtil.copyToList(userList,AuthUserBO.class);

    }
}
